# -*- coding: utf-8 -*-
"""
Module Description: 资源库基类
"""
import framework.distribute.mutex as mutex
from framework.dal.dal_adapters.adapter_settings import lock_cfg
from utils.dict_utils import chunks


class BaseRepository(object):
    """资源库基类"""

    # 资源库对应的模型适配器类, 用于支持基类提供的通用方法
    adapter_class = None
    # 最大预处理数
    max_prepared_stmt_count = 5000  # 16382

    @classmethod
    def query_all(cls):
        """查询所有"""
        return cls.adapter_class.objects.all()

    @classmethod
    def create_many(cls, data_list):
        """批量创建"""
        # 最大预处理数分片插入
        for data in chunks(data_list, cls.max_prepared_stmt_count):
            cls.adapter_class.objects.insert_many(data)

    @classmethod
    def total_count(cls):
        """表记录条数"""
        return cls.adapter_class.objects.count()

    @classmethod
    def save(cls, *mdls):
        """
        保存修改的模型对象
        :param mdls: Model列表
        :return:
        """
        for mdl in mdls:
            mdl.save()

    @classmethod
    def delete(cls, *mdls):
        """
        删除修改的模型对象
        :param mdls:
        :return:
        """
        for mdl in mdls:
            mdl.delete()

    @classmethod
    def lock(cls, overtime_sec=None, need_lock=True, server_id=None, **kwargs):
        """
        根据当前适配器加锁

        加锁必须传入的字段配置,见pyshare.dal.dal_adapters.adapter_setting.py::lock_cfg
        :param kwargs: 加锁参数
        :param overtime_sec: 锁超时时间
        :param need_lock: 控制是否真实加锁
        :param server_id: 区服id
        :return:
        """
        table_name = cls.adapter_class.model_class.__name__
        if len(set(lock_cfg[table_name]) - set(kwargs.keys())) != 0:
            raise KeyError, "LockParameterNotEqual"

        param_list = []
        for key in lock_cfg[table_name]:
            param_list.append(str(kwargs[key]))
        guid = "_".join(param_list)

        adapter_key = "{tablename}:{guid}".format(
            tablename=table_name,
            guid=guid
        )

        return mutex.RMutex(adapter_key, overtime_sec=overtime_sec, need_lock=need_lock, server_id=server_id)

